package com.northpool.operator.analysis.overlap;

import com.northpool.operator.annotation.InputParam;
import com.northpool.operator.annotation.InputParams;
import com.northpool.operator.annotation.OperatorInfo;
import com.northpool.operator.common.algorithm.OperatorTestBuild;
import com.northpool.operator.common.algorithm.TestParamBuilder;
import com.northpool.operator.common.stpclient.StpClientOperatorBase;
import com.northpool.operator.param.ParamTool;
import com.northpool.operator.param.custom.DatasetParam;
import com.northpool.operator.type.TypeEnum;
import com.northpool.stpclient.bean.BaseResponse;
import com.northpool.stpclient.modules.geoprocess.operator.IPipelineOperator;
import com.northpool.stpclient.operator.bean.DatasetBean;
import com.northpool.stpclient.operator.bean.OperatorBean;
import com.northpool.stpclient.operator.bean.ParamBean;
import com.northpool.stpclient.operator.bean.PipelineBean;

import java.io.File;
import java.util.LinkedList;
import java.util.List;

@OperatorInfo(
        ref = "Buffer4WidthValueOperator",
        name = "数值型缓冲区分析",
        description = "叠加分析-数值型缓冲区分析"
)
public class                                                                                                                                                                                                                                                                                                                                  Buffer4WidthValueOperator extends StpClientOperatorBase {
    String dataSourceId;
    String tableName;
    String spatialField;
    String sqlFilter;
    String bufferWidth;
    String targetDataSourceId;
    String targetTableName;
    String templateDataSourceId;
    String templateTableName;

    @InputParams({
            @InputParam(ref = "dataset", name = "数据集", desc = "数据集包含数据源ID和数据表名称的JSON描述，如: {\"dataSourceId\":\"xxx-xxx\",\"tableName\":\"table\"}", type = TypeEnum.DB, required = true, testValue = ""),
            @InputParam(ref = "spatialField", name = "空间字段", desc = "空间字段名称，如: geom", type = TypeEnum.STRING, required = true),
            @InputParam(ref = "sqlFilter", name = "SQL过滤条件", desc = "SQL过滤条件, 如: dlmc = '旱地'", type = TypeEnum.STRING, required = false),
            @InputParam(ref = "bufferWidth", name = "缓冲宽度", type = TypeEnum.STRING, required = true),
            @InputParam(ref = "targetDataSourceId", name = "结果数据源ID", desc = "目标数据源ID", type = TypeEnum.DATASOURCE, required = true),
            @InputParam(ref = "targetTableName", name = "结果数据集名称", desc = "目标表名称", type = TypeEnum.STRING, required = true),
            @InputParam(ref = "templateDataSourceId", name = "模板数据源ID", type = TypeEnum.DATASOURCE, required = true),
            @InputParam(ref = "templateTableName", name = "模板数据集名称", type = TypeEnum.STRING, required = true),
    })
    public Buffer4WidthValueOperator() {
        super();
    }

    public static void main(String[] args) throws Exception {
        OperatorTestBuild.execute(Buffer4WidthValueOperator.class, TestParamBuilder.aBuilder()
                        .param("dataset", "")
                        .param("spatialField", "the_geom")
                        .param("sqlFilter", "dlmc = '旱地'")
                        .param("bufferWidth", "buffer_width")
                        .param("targetDataSourceId", "402881ad9310bde101931141d66a0015")
                        .param("targetTableName", "dltb_result")
                        .param("templateDataSourceId", "402881ad9310bde101931141d66a0015")
                        .param("templateTableName", "dltb_template")
                .build());
    }


    @Override
    public void execute(ParamTool params) throws Exception {
        DatasetParam dataset = params.getDataset("dataset");

        this.dataSourceId = dataset.getDataSourceId();
        this.tableName = dataset.getTableName();
        this.spatialField = params.getStr("spatialField");
        this.sqlFilter = params.getStr("sqlFilter");
        this.bufferWidth = params.getStr("bufferWidth");

        this.targetDataSourceId = params.getStr("targetDataSourceId");
        this.targetTableName = params.getStr("targetTableName");
        this.templateDataSourceId = params.getStr("templateDataSourceId");
        this.templateTableName = params.getStr("templateTableName");

        List<OperatorBean> ops = new LinkedList<>();
        ops.add(buildBuffer());

        PipelineBean pipeline = new PipelineBean();
        pipeline.setResultFile(System.getProperty("user.dir") + File.separator + "result_file");
        DatasetBean dataSet = new DatasetBean();
        dataSet.setDataSourceId(dataSourceId);
        dataSet.setTableName(tableName);
        dataSet.setSqlFilter(sqlFilter);
        pipeline.setDataSet(dataSet);

        pipeline.setOperators(ops);
        IPipelineOperator iPipelineOperator = this.client.pipelineOperator();
        BaseResponse response = iPipelineOperator.startPipeline(pipeline);
        iPipelineOperator.onStart(response.getRequestId(), () -> {
            this.log("Buffer开始");
        });
        iPipelineOperator.onSuccess(response.getRequestId(), () -> {
            this.log("Buffer成功");
            String log = iPipelineOperator.log(response.getRequestId());
            this.log(log);
            this.successExit();
        });
        iPipelineOperator.onError(response.getRequestId(), () -> {
            this.error("Buffer失败");
            String log = iPipelineOperator.log(response.getRequestId());
            this.error(log);
            this.failedExit();
        });
        this.waiting(24);
    }

    public OperatorBean buildBuffer() {
        OperatorBean operatorBean = new OperatorBean();
        operatorBean.setClassName("com.northpool.stpprocess.operator.spatial.vector.BufferOperator");

        List<ParamBean> params = new LinkedList<>();
        params.add(new ParamBean("spatialField", spatialField));
        params.add(new ParamBean("缓冲宽度", bufferWidth));
        operatorBean.setStartParam(params);

        return operatorBean;
    }

    public OperatorBean buildPgSink() {
        OperatorBean operatorBean = new OperatorBean();
        operatorBean.setClassName("com.northpool.stpprocess.operator.basic.sink.PostgresSink");

        List<ParamBean> params = new LinkedList<>();
        params.add(new ParamBean("dataSourceId", targetDataSourceId));
        params.add(new ParamBean("tableName", targetTableName));
        params.add(new ParamBean("templateDataSourceId", templateDataSourceId));
        params.add(new ParamBean("templateTableName", templateTableName));
        operatorBean.setStartParam(params);

        return operatorBean;
    }
}
